package util

import (
	"bytes"
	"github.com/howcrazy/xconv"
	"net/url"
	"reflect"
	"sort"
	"strings"
	"unsafe"
)

var Strings = mstrings{}

type mstrings struct {
}

func (domain mstrings) str2bytes(s string) []byte {
	x := (*[2]uintptr)(unsafe.Pointer(&s))
	h := [3]uintptr{x[0], x[1], x[1]}
	return *(*[]byte)(unsafe.Pointer(&h))
}

func (domain mstrings) bytes2str(b []byte) string {
	return *(*string)(unsafe.Pointer(&b))
}
func (domain mstrings) spliceUrl(url string, data map[string]string) string {
	buffer := bytes.Buffer{}
	buffer.WriteString(url)
	buffer.WriteString("?")
	buffer.WriteString(Strings.EncodeFormStr(data))
	return buffer.String()
}
func (domain mstrings) EncodeFormStr(data map[string]string) string {
	if data == nil {
		return ""
	}
	var buf strings.Builder
	keys := make([]string, 0, len(data))
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		v := data[k]
		keyEscaped := url.QueryEscape(k)

		if buf.Len() > 0 {
			buf.WriteByte('&')
		}
		buf.WriteString(keyEscaped)
		buf.WriteByte('=')
		buf.WriteString(url.QueryEscape(v))

	}
	return buf.String()
}
func (domain mstrings) EncodeForm(data map[string]interface{}) string {
	if data == nil {
		return ""
	}
	var buf strings.Builder
	keys := make([]string, 0, len(data))
	for k := range data {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	for _, k := range keys {
		v := data[k]
		keyEscaped := url.QueryEscape(k)

		if buf.Len() > 0 {
			buf.WriteByte('&')
		}
		buf.WriteString(keyEscaped)
		buf.WriteByte('=')
		var value string
		xconv.Convert(v, &value)
		buf.WriteString(url.QueryEscape(value))

	}
	return buf.String()
}
func (domain mstrings) NotNull(val interface{}) bool {
	if val == nil {
		return false
	}
	switch reflect.TypeOf(val).Kind() {
	case reflect.String:
		return val != ""
	case reflect.Int:
		return val != 0
	case reflect.Int8:
		return val != 0
	case reflect.Int16:
		return val != 0
	case reflect.Int32:
		return val != 0
	case reflect.Int64:
		return val != 0
	case reflect.Float32:
		return val != 0.0
	case reflect.Float64:
		return val != 0.0
	default:
		return true
	}
}
